/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.factory.server.scheduler;

import com.factory.server.consumers.SchedulerTasksQueue;
import com.factory.server.json.Plan;
import java.util.ArrayList;
import java.util.List;

/**
 * Dynamically computes offset for offered time plans. It is based on taksk queue and number of threads.
 * @author milos
 */
public class MachineList {

    private List<List<Plan>> machinesQueues;
    private List<Plan> minimalQueue;
    private int number;

    public MachineList(int number) {
        this.number = number;

        machinesQueues = new ArrayList<List<Plan>>(number);
        for (int i = 0; i < number; i++) {
            machinesQueues.add(new ArrayList<Plan>());
        }
        minimalQueue = machinesQueues.get(0);
    }

    public void schedule(SchedulerTasksQueue tasksQueue) {

        for (Plan plan : tasksQueue.getPlans()) {
            add(plan);
        }
    }

    private void add(Plan plan) {
        minimalQueue = getMinimalQueue();
        minimalQueue.add(plan);
    }

    private List<Plan> getMinimalQueue() {
//        int sum = 0;
        if (machinesQueues.get(0) == null || machinesQueues.get(0).isEmpty()) {
            return machinesQueues.get(0);

        }
        long minimum = machinesQueues.get(0).get(machinesQueues.get(0).size() - 1).getTimeMillis();
        List<Plan> minimalQueueTemp = machinesQueues.get(0);

        for (List<Plan> list : machinesQueues) {
            if (list.isEmpty()) {
                return list;
            }
            if (minimum > list.get(list.size() - 1).getTimeMillis()) {
                minimum = list.get(list.size() - 1).getTimeMillis();
                minimalQueueTemp = list;
            }
        }
        return minimalQueueTemp;
    }

    public int getOffset(SchedulerTasksQueue taskQueue, Plan plan) {
        
        if (taskQueue.getPlans().size() > 0){
            System.out.println("taskQueue size in getOffset() is more than 0: "+taskQueue.getPlans().size());
        }
        SchedulerTasksQueue requeuedTaskQueue;
        if (plan.getDeadline() == 0) { //if priority task, going to change order
            requeuedTaskQueue = queuePriorityPlan(taskQueue.clone(), plan);
            schedule(requeuedTaskQueue);
        } else {
            schedule(taskQueue);
        }
        List<Plan> minimalQueueTmp = getMinimalQueue();
        if (minimalQueueTmp.isEmpty()) {
            return 0;
        } else {
            return (int) minimalQueueTmp.get(minimalQueueTmp.size() - 1).getTimeMillis();
        }
    }

    private SchedulerTasksQueue queuePriorityPlan(SchedulerTasksQueue taskQueue, Plan priorityPlan) {
        List<Plan> plans = taskQueue.getPlans();
        Plan plan;
        for (int i = plans.size() - 1; i >= number; i--) {   //pretoze prave "n" sa moze prave uz spracovavat
            plan = plans.get(i);
            if (priorityPlan.getComputationTime() < plan.getDeadline() - plan.getPlannedFinishTime()) {
                plans.remove(i);
            }
        }
  
        return taskQueue;
    }
}
